package com.wuwei.elearning.question.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wuwei.elearning.enumPackage.Constant;
import com.wuwei.elearning.exception.ElearningMysqlException;
import com.wuwei.elearning.question.domain.Audio;
import com.wuwei.elearning.question.domain.ListenRecord;
import com.wuwei.elearning.question.mapper.AudioMapper;
import com.wuwei.elearning.question.mapper.ListenRecordMapper;
import com.wuwei.elearning.question.service.AudioService;
import com.wuwei.elearning.question.vo.AudioVo;
import com.wuwei.elearning.service.CacheService;
import com.wuwei.elearning.setting.mapper.UserMapper;
import com.wuwei.elearning.utils.AudioUtil;
import com.wuwei.elearning.utils.FileUtils;
import com.wuwei.elearning.utils.MinioUtil;
import com.wuwei.elearning.utils.result.Result;
import com.wuwei.elearning.utils.token.TokenUtil;
import io.minio.GetObjectResponse;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/elearning/audio")
public class AudioController {



    @Resource
    private AudioService audioService;


    @SneakyThrows
    @PostMapping("upload")
    public Result<String> upload( MultipartFile file, HttpServletRequest request){
        if (file.getSize() != 0) {
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
            if (!"mp3".toUpperCase().contains(suffix.toUpperCase())) {
                return Result.fail("请选择mp3格式的音频");
            }

            if (file.getSize()!=0) {
                File file1 = FileUtils.convertMultipartFileToFile(file);
                Float durationSeconds = AudioUtil.getMp3Duration(file1);
                // 计算分钟数和剩余的秒数
                int minutes = (int) (durationSeconds / 60);
                int seconds = (int) (durationSeconds % 60);
                String duration = String.format("%d分%d秒", minutes, seconds);
                String token = request.getHeader("Authorization");
                Long account = TokenUtil.getAccountFromToken(token);
                audioService.insert(file,account,duration);
                return Result.ok("上传成功");
            }
            return Result.fail("上传失败！");
        } else {
            return Result.fail("您没有上传任何文件");
        }
    }


    @Resource
    private AudioMapper audioMapper;

    @Resource
    private ListenRecordMapper listenRecordMapper;

    /**
     * 只显示答案和问题都不是空的所有音频信息的方法
     * @param params
     * @return
     */
    @GetMapping("getListForTest")
    public Result<List<AudioVo>> getListForTest(@RequestParam Map<String, String> params, HttpServletRequest request){
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);

        String fileName = params.get("fileName");
        Integer currentPage = Integer.parseInt(params.get("currentPage"));
        Integer pageSize = Integer.parseInt(params.get("pageSize"));
        Integer skipPage = (currentPage-1)*pageSize;
        List<AudioVo> list = audioMapper.mySelectList(fileName,pageSize,skipPage);
//        //todo 这里多次查询了数据库，后续肯定要优化
//        list.forEach(a->{
//            Long audioId = a.getId();
//            LambdaQueryWrapper<ListenRecord> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.eq(ListenRecord::getAudioId,audioId).eq(ListenRecord::getAccount,account);
//            ListenRecord listenRecord = listenRecordMapper.selectOne(queryWrapper);
//            if (listenRecord!=null) {
//                a.setScore(listenRecord.getScore());
//            }
//        });
        if (!list.isEmpty()) {
            // 2. 提取所有音频ID
            List<Long> audioIds = list.stream()
                    .map(AudioVo::getId)
                    .collect(Collectors.toList());

            // 3. 一次性查询所有相关的听力记录
            LambdaQueryWrapper<ListenRecord> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ListenRecord::getAudioId, audioIds)
                    .eq(ListenRecord::getAccount, account);
            List<ListenRecord> records = listenRecordMapper.selectList(queryWrapper);

            // 4. 将听力记录转换为Map，方便查找
            Map<Long, Integer> audioScoreMap = records.stream()
                    .collect(Collectors.toMap(
                            ListenRecord::getAudioId,
                            ListenRecord::getScore
                    ));

            // 5. 设置分数
            list.forEach(audio -> {
                audio.setQuestions(null);
                audio.setAnswers(null);
                audio.setScore(audioScoreMap.get(audio.getId()));
            });
        }
        return Result.ok(list);
    }

    /**
     * 显示所有音频信息的方法
     * @param params
     * @param request
     * @return
     */
    @GetMapping("getList")
    public Result<List<Audio>> getList(@RequestParam Map<String, String> params,HttpServletRequest request){
        String fileName = params.get("fileName");
        Integer currentPage = Integer.parseInt(params.get("currentPage"));
        Integer pageSize = Integer.parseInt(params.get("pageSize"));
        LambdaQueryWrapper<Audio> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(!"".equals(fileName),Audio::getName,fileName);

        IPage<Audio> page = new Page<>();
        page.setSize(pageSize);
        page.setCurrent(currentPage);

        IPage<Audio> audioIPage = audioMapper.selectPage(page, wrapper);
        List<Audio> records = audioIPage.getRecords();

        for (Audio audio : records) {
            String path = audio.getPath();
            String redisKey = Constant.MINIO_AUDIO + path;
            String url = cacheService.getAudio(path, redisKey);
            audio.setPath(url);
        }
        return Result.ok(records);
    }

    @Resource
    private CacheService cacheService;


    @GetMapping("getTotal")
    public Result<Long> getTotal(@RequestParam Map<String, String> params){
        String fileName = params.get("fileName");
        LambdaQueryWrapper<Audio> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!"".equals(fileName),Audio::getName,fileName);
        Long count = audioMapper.selectCount(queryWrapper);
        return Result.ok(count);
    }

    @PostMapping("update")
    public Result<String> update(@RequestBody Audio audio){
        audioService.myUpdateById(audio);
        return Result.ok("设置成功");
    }

    @PostMapping("delete/{id}")
    public Result<String> delete(@PathVariable("id") Long id){
        audioService.deleteById(id);
        return Result.ok("删除成功！");
    }

    @GetMapping("getById/{id}")
    public Result<Audio> getById(@PathVariable("id") Long id){
        Audio audio = audioMapper.selectById(id);
        if (audio==null) {
            throw new ElearningMysqlException(30011,"查询失败！");
        } else {
            String path = audio.getPath();
            String redisKey = Constant.MINIO_AUDIO + path;
            String url = cacheService.getAudio(path, redisKey);
            audio.setPath(url);
            return Result.ok(audio);
        }
    }

    @Resource
    private MinioUtil minioUtil;

    @GetMapping("/stream")
    public ResponseEntity<byte[]> streamAudio(@RequestParam String fileName) {
        GetObjectResponse object = minioUtil.getObject(fileName);

        try {
            ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = object.read(buffer)) != -1) {
                byteArray.write(buffer, 0, bytesRead);
            }

            byte[] data = byteArray.toByteArray();

            HttpHeaders headers = new HttpHeaders();
            // 设置正确的内容类型
            headers.setContentType(MediaType.parseMediaType("audio/mpeg"));
            headers.setContentLength(data.length);
            // 添加 CORS 头
            headers.add("Access-Control-Allow-Origin", "*");
            headers.add("Access-Control-Allow-Methods", "GET, OPTIONS");
            headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(data);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        } finally {
            try {
                object.close();
            } catch (IOException e) {
                // 处理关闭流的异常
            }
        }
    }

}
